const express = require('express');
const { createServer } = require('http');
const { Server } = require('socket.io');
const debug = require('debug')('tunnel:server');

const app = express();
const httpServer = createServer(app);
const io = new Server(httpServer, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"]
  }
});

// 添加 body-parser 中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 存储隧道信息
const tunnels = new Map();

// 从环境变量获取域名和端口
const TUNNEL_DOMAIN = process.env.TUNNEL_DOMAIN || '23908.dev.d8dcloud.com';
const PORT = process.env.PORT || 23909;

io.on('connection', (socket) => {
  debug('客户端连接:', socket.id);

  // 客户端注册隧道
  socket.on('register', (data) => {
    const { localPort } = data;
    const tunnelId = Math.random().toString(36).substr(2, 9);
    
    tunnels.set(tunnelId, {
      socket,
      localPort,
      createdAt: new Date()
    });

    debug('隧道已注册:', tunnelId, localPort);
    
    // 根据环境生成不同格式的 URL
    const isTestEnv = process.env.NODE_ENV === 'test';
    const url = isTestEnv 
      ? `https://${TUNNEL_DOMAIN}?tunnel=${tunnelId}`  // 测试环境：查询参数形式
      : `https://${tunnelId}.${TUNNEL_DOMAIN}`;        // 生产环境：子域名形式
    
    socket.emit('registered', { tunnelId, url });
  });

  // 处理请求转发
  socket.on('response', (data) => {
    const { requestId, response } = data;
    debug('收到响应:', requestId, '状态码:', response.status);
    
    // 广播响应给所有连接的客户端（包括代理服务器）
    io.emit('proxyResponse', { requestId, response });
  });

  // 处理断开连接
  socket.on('disconnect', () => {
    debug('客户端断开:', socket.id);
    // 清理隧道
    for (const [tunnelId, tunnel] of tunnels.entries()) {
      if (tunnel.socket.id === socket.id) {
        tunnels.delete(tunnelId);
        debug('隧道已删除:', tunnelId);
      }
    }
  });

  // 心跳检测
  socket.on('ping', () => {
    socket.emit('pong');
  });

  // 处理代理服务器的请求
  socket.on('proxyRequest', (data) => {
    const { requestId, tunnelId, request } = data;
    debug('收到代理请求:', requestId, tunnelId);

    const tunnel = tunnels.get(tunnelId);
    if (!tunnel) {
      // 直接回复给发送请求的 socket
      socket.emit('proxyResponse', {
        requestId,
        response: {
          status: 404,
          headers: { 'content-type': 'text/plain' },
          body: 'Tunnel not found'
        }
      });
      return;
    }

    // 转发请求到对应的隧道客户端
    tunnel.socket.emit('request', {
      ...request,
      id: requestId  // 确保 requestId 被正确传递
    });
  });
});

// 移除原有的 HTTP 请求处理逻辑，因为现在由代理服务器处理
app.use((req, res) => {
  res.status(404).send('Please use proxy server');
});

// 错误处理
app.use((err, req, res, next) => {
  debug('错误:', err);
  res.status(500).send('Internal Server Error');
});

httpServer.listen(PORT, () => {
  debug(`服务器运行在端口 ${PORT}`);
});

module.exports = { app, httpServer, io };
